/*
 ********************************************************************************
 * @FileName  : button.c
 * @CreateDate: 2021-8-7
 * @Author    : GaoQiu
 * @Copyright : Copyright(C) GaoQiu
 *              All Rights Reserved.
 ********************************************************************************
 */
#include "board/board.h"
#include "button.h"
#include "platform/platform.h"
#include "keyboard.h"

#ifndef BTN_PINS
#define BTN_PINS   {0}
#endif

#ifndef BTN_MAPS
#define BTN_MAPS  {0}
#endif

BtnData_t btnData;

#define BTN_FILTER_NUM  4

typedef struct{
	BtnMask_t   pressedMask;
	BtnMask_t   history[BTN_FILTER_NUM];
	BtnMask_t   lasePressedMask;
	uint16_t    pins[BTN_MAX_NUM];
	uint8_t     btnMap[BTN_MAX_NUM];
}BtnCb_t;

BtnCb_t btnCb;

 bool_t Btn_IsChanged(uint32_t pressedMask)
 {
	 bool_t btnChanged = false;

	 for(int i=BTN_FILTER_NUM-1; i>0; --i){
		 btnCb.history[i] = btnCb.history[i-1];
	 }
	 btnCb.history[0] = pressedMask;

	 if(btnCb.history[0] == btnCb.history[1] && btnCb.history[1] == btnCb.history[2] &&
	    btnCb.history[0] != btnCb.lasePressedMask){
		 btnChanged = true;

		 btnCb.lasePressedMask = btnCb.history[0];
	 }

	 return btnChanged;
 }

bool_t Btn_Scan(void)
{
	btnData.cnt = 0;

	btnCb.pressedMask = 0;

	for(int i=0; i<BTN_MAX_NUM; i++)
	{
		if(GPIO_ReadInputBitEx(btnCb.pins[i]) == BTN_VALID_LVL){
			btnCb.pressedMask |= BIT(i);
		}
	}

	bool_t btnChanged = Btn_IsChanged(btnCb.pressedMask);
	if(btnChanged)
	{
		for(int i=0; i<BTN_MAX_NUM; i++)
		{
			if(btnCb.pressedMask & BIT(i)){
				btnData.code[btnData.cnt++] = btnCb.btnMap[i];
			}
		}
	}

	return btnChanged;
}

BtnData_t *Btn_GetData(void)
{
	return &btnData;
}


void Btn_Init(void)
{
	uint16_t pins[] = BTN_PINS;
	uint8_t map[] = BTN_MAPS;

	memset(&btnCb,0, sizeof(BtnCb_t));

	memcpy(btnCb.pins, pins, BTN_MAX_NUM*2);
	memcpy(btnCb.btnMap, map, BTN_MAX_NUM);

	for(int i=0; i<BTN_MAX_NUM; i++)
	{
		GPIO_InitEx(btnCb.pins[i], GPIO_Mode_In);
		GPIO_SetPullModeEx(btnCb.pins[i], GPIO_PullUp_Strong);//[!!! important]
	}
}



